#include "Expression.h"

#include <iostream>
#include <cstdlib>
#include <cstdio>

#include <string.h>

using namespace COOLangage;

COOLangage::Expression::Expression() {
}

COOLangage::Expression::~Expression() throw() {
}

VisitorResult COOLangage::Expression::visit(VisitorExpression *visitor) {
  return visitor->visitExpression(this);
}

// -------------------------------------------------------------------------------

COOLangage::Appel::Appel(const char* name) {
  methodname = strdup(name);
}

COOLangage::Appel::~Appel() throw(){
  free(methodname);
}

void COOLangage::Appel::addArgument(Expression *expr) {
  arguments.push_back(expr);
}

const std::vector<Expression*> COOLangage::Appel::getArguments() const {
  return arguments;
}

const char* COOLangage::Appel::getMethodName() const {
  return methodname;
}

int COOLangage::Appel::size() const {
  return arguments.size();
}

Expression* COOLangage::Appel::operator[] (int index) const {
  return arguments[index];
}

VisitorResult COOLangage::Appel::visit(VisitorExpression *visitor) {
  return visitor->visitAppel(this);
}
// -------------------------------------------------------------------------------
VisitorResult COOLangage::LitEntier::visit(VisitorExpression *visitor) {
  return visitor->visitLitEntier(this);
}

VisitorResult COOLangage::LitFlottant::visit(VisitorExpression *visitor) {
  return visitor->visitLitFlottant(this);
}
// -------------------------------------------------------------------------------
COOLangage::Operateur::Operateur(const char * symbol) {
  this->symbol = strdup(symbol);
}

COOLangage::Operateur::~Operateur() throw() {
  free(symbol);
}

VisitorResult COOLangage::Operateur::visit(VisitorExpression *visitor) {
  return visitor->visitOperateur(this);
}

// -------------------------------------------------------------------------------
COOLangage::OperateurUnaire::OperateurUnaire(const char *const symbol, Expression *operand) :
  Operateur(symbol), operand(operand) {
}

COOLangage::OperateurUnaire:: ~OperateurUnaire() throw() {
  if(operand != NULL)
    delete operand;
}

int COOLangage::OperateurUnaire::size() const {
  return 1;
}

Expression * COOLangage::OperateurUnaire::getOperand() const {
  return operand;
}

VisitorResult COOLangage::OperateurUnaire::visit(VisitorExpression *visitor) {
  return visitor->visitOperateurUnaire(this);
}

// -------------------------------------------------------------------------------
COOLangage::OperateurBinaire::OperateurBinaire(const char* symbol, 
					       Expression *left, Expression *right)
  : Operateur(symbol), left(left), right(right)
{
  
}

COOLangage::OperateurBinaire::~OperateurBinaire() throw() {
  if(left != NULL)
    delete left;
  if(right != NULL)
    delete right;
}
		
int COOLangage::OperateurBinaire::size() const {
  return 2;
}

Expression* COOLangage::OperateurBinaire::getLeft() const {
  return left;
}

Expression* COOLangage::OperateurBinaire::getRight() const {
  return right;
}

VisitorResult COOLangage::OperateurBinaire::visit(VisitorExpression *visitor) {
  return visitor->visitOperateurBinaire(this);
}

// -------------------------------------------------------------------------------

COOLangage::Variable::Variable(const char* name) {
  this->name = strdup(name);
}

COOLangage::Variable::~Variable() throw() {
  free(name);
}

const char * COOLangage::Variable::getName() const {
  return name;
}

VisitorResult COOLangage::Variable::visit(VisitorExpression *visitor) {
  return visitor->visitVariable(this);
}

// -------------------------------------------------------------------------------
